package com.lipaluma.field.validator.impl.string;
import java.lang.reflect.Field;
import java.util.List;
import java.util.regex.Pattern;

import com.lipaluma.annotations.validations.Validate;
import com.lipaluma.context.Context;
import com.lipaluma.field.validator.ValidationError;
import com.lipaluma.field.validator.Validator;
import com.lipaluma.xml.validator.XmlMatchesValidator;
import com.lipaluma.xml.validator.XmlValidator;

/**
 * Validator for String field that check if this value matches a given pattern regex.<br/>
 *  
 * To initialize :
 * <ul>
 * 	<li>
 * 	<u><b>By annotations :</b></u> Use {@link Validate} and use the <code>matches</code> attribute to 
 * specify the regex to check.<br/>
 * 	</li>
 * 	<li>
 * 	<u><b>By Xml :</b></u>
 * <ul>
 * <li>
 * To add the endsWith validation, see the example below : <br/>
 * <code>
 * &lt;ToMap field="..." ><br/>
 * <b>
 * &nbsp;&nbsp;&nbsp;&lt;matches regex="value regex"/><br/>
 * </b>
 * &lt;/toMap><br/>
 * </code>
 * </li>
 * </ul>
 * 
 * @author msoares
 *
 */
public class StringMatchesValidator implements Validator {

	private String regex;
	private Pattern pattern;
	
	public StringMatchesValidator() {}
	public StringMatchesValidator(String pattern) {
		this.regex = pattern;
		this.pattern = Pattern.compile(pattern);
	}
	
	public boolean init(Context context, Field field) {
		Validate annotation = field.getAnnotation(Validate.class);
		if(annotation == null || annotation.matches().isEmpty())
			return false;
		this.regex = annotation.matches();
		this.pattern = Pattern.compile(annotation.matches());
		return true;
	}

	public boolean init(Context context, Field field, XmlValidator xmlValidator) {
		XmlMatchesValidator validator = (XmlMatchesValidator) xmlValidator;
		this.regex = validator.getRegex();
		this.pattern = Pattern.compile(validator.getRegex());
		return true;
	}
	
	public boolean validate(Object value, List<ValidationError> errors) {
		if(!pattern.matcher(value.toString()).matches()) {
			errors.add(new ValidationError("The value "+value+" doesn't match the pattern "+regex));
			return false;
		}
		return true;
	}

}
